using UnityEngine;
using QFramework;
using UnityEngine.EventSystems;

// 1.请在菜单 编辑器扩展/Namespace Settings 里设置命名空间
// 2.命名空间更改后，生成代码之后，需要把逻辑代码文件（非 Designer）的命名空间手动更改
namespace QFramework.Example
{
	public partial class UISlot : ViewController,IBeginDragHandler,IDragHandler,IEndDragHandler,IPointerEnterHandler,IPointerExitHandler
	{
		public Slot Data { get; set; }

		// 是否正在拖拽中
		private bool mDraging = false;

		public UISlot InitWithData(Slot data)
		{
			// 如果Data不为空，证明之前已经初始化过了，需要先注销之前的监听
			if (Data!=null)
			{
				Data.Changed.UnRegister(UpdateView);
			}
			
			Data = data;
			// 注册格子数据变化的事件
			Data.Changed.Register(() =>
			{
				UpdateView();
			}).UnRegisterWhenGameObjectDestroyed(gameObject);
			
			UpdateView();
			return this;
		}
		
		void UpdateView()
		{
			if (Data.Count==0)
			{
				Icon.Hide();
				//Name.text = "空";
				Count.text = "";
			}
			else
			{
				Icon.Show();
				if (Data.Item.GetIcon)
				{
					// 如果item有icon的话，则展示对应的icon
					Icon.sprite = Data.Item.GetIcon;
				}
				//Name.text = Data.Item.Name;
				if (!Data.Item.IsStackable)
				{
					Count.Hide();
				}
				else
				{
					Count.text = Data.Count.ToString();
					Count.Show();
				}
			}
		}
		
		/// <summary>
		/// 开始拖动
		/// </summary>
		/// <param name="eventData"></param>
		public void OnBeginDrag(PointerEventData eventData)
		{
			// 如果正在拖拽中，或者当前格子里没有道具，则返还
			if (mDraging||Data.Count<=0) return;
			mDraging = true;

			// 把Name的父节点设置为顶点，让拖动时Name显示一直处于最上层
			var canvas = Icon.gameObject.AddComponent<Canvas>();
			canvas.overrideSorting = true;
			// 把摄像机设置为SortingOrder为1000，这样拖动时slot会显示在最上层
			canvas.sortingOrder = 1000;
			
			SyncItemToMousePos();
		}

		/// <summary>
		/// 拖动中
		/// </summary>
		/// <param name="eventData"></param>
		public void OnDrag(PointerEventData eventData)
		{
			if (mDraging)
			{
				SyncItemToMousePos();
			}
		}

		/// <summary>
		/// 拖动结束时
		/// </summary>
		/// <param name="eventData"></param>
		public void OnEndDrag(PointerEventData eventData)
		{
			if (mDraging)
			{
				mDraging= false;
				// 设置Name的局部位置为zero，这样就相当于物品回到了所在的格子里
				var canvas = Icon.GetComponent<Canvas>();
				canvas.DestroySelf();
				Icon.LocalPositionIdentity();
				
				// 判断是否有放在其它UISlot的上面，如果没有，则视为丢弃
				if (ItemKit.CurrentSlotPointerOn)
				{
					var slot = ItemKit.CurrentSlotPointerOn;
					var rectTransform = slot.transform as RectTransform;
					// 如果鼠标的位置在slot的格子范围内，则不丢弃，而是替换到该格子里
					if (RectTransformUtility.RectangleContainsScreenPoint(rectTransform,Input.mousePosition))
					{
						// 如果目标格子里有物品，才进行交换
						if (Data.Count>0)
						{
							// 当拖动的道具和目标格子的属性是一致时，才能进行替换，比如常规道具无法放到装备栏里
							if (slot.Data.Group.CheckCondition(Data.Item))
							{
								var cacheItem = slot.Data.Item;
								var cacheCount = slot.Data.Count;

								slot.Data.Item = Data.Item;
								slot.Data.Count = Data.Count;

								Data.Item = cacheItem;
								Data.Count = cacheCount;
							
								// 触发格子变化事件
								slot.Data.Changed.Trigger();
								Data.Changed.Trigger();
								
								// 触发格子内信息变化事件
								slot.Data.Group.Changed.Trigger();
								Data.Group.Changed.Trigger();
							}
						}
					}
				}
				else
				{
					// 如果没有检测到任何格子，则视为丢弃
					Data.Item = null;
					Data.Count = 0;
					Data.Changed.Trigger();
				}
			}
		}

		/// <summary>
		/// 同步Item到鼠标当前位置
		/// </summary>
		private void SyncItemToMousePos()
		{
			// 获取当前鼠标位置
			var mousePos = Input.mousePosition;
			// 把鼠标位置转换为UI的位置，然后把拖动的UI位置赋值到该位置
			if (RectTransformUtility.ScreenPointToLocalPointInRectangle(transform as RectTransform,
				    mousePos,null,out var localPos))
			{
				Icon.LocalPosition(localPos);
			}
		}

		public void OnPointerEnter(PointerEventData eventData)
		{
			UIItemTip.Show(this);
			// if (Data.Item!=null)
			// {
			// 	Debug.Log(Data.Item.GetName);
			// }
			ItemKit.CurrentSlotPointerOn = this;
		}

		public void OnPointerExit(PointerEventData eventData)
		{
			UIItemTip.Hide();
			if (ItemKit.CurrentSlotPointerOn==this)
			{
				ItemKit.CurrentSlotPointerOn = null;
			}
		}
	}
}
